{/* Copyright 2020 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License. */}

import {Layout} from '@react-spectrum/docs';
export default Layout;

import docs from 'docs:@react-aria/color';
import statelyDocs from 'docs:@react-stately/color';
import {HeaderInfo, FunctionAPI, TypeContext, InterfaceType, TypeLink, PageDescription} from '@react-spectrum/docs';
import packageData from '@react-aria/color/package.json';
import Anatomy from './ColorFieldAnatomy.svg';

---
category: Color
keywords: [color, input, color picker, aria]
---

# useColorField

<PageDescription>{docs.exports.useColorField.description}</PageDescription>

<HeaderInfo
  packageData={packageData}
  componentNames={['useColorField']}
  sourceData={[
    {type: 'W3C', url: 'https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/'}
  ]} />

## API

<FunctionAPI function={docs.exports.useColorField} links={docs.links} />

## Features

The [&lt;input type="color"&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color) HTML element
can be used to build a color picker, however it is very inconsistent across browsers and operating systems and consists
of a complete color picker rather than a single field for editing a hex value. `useColorField` helps achieve accessible
color fields that can be styled as needed.

* Support for parsing and formatting a hex color value
* Validates keyboard entry as the user types so that only valid hex characters are accepted
* Supports using the arrow keys to increment and decrement the value
* Exposed to assistive technology as a `textbox` via ARIA
* Visual and ARIA labeling support
* Follows the [spinbutton](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/) ARIA pattern
* Works around bugs in VoiceOver with the spinbutton role
* Uses an ARIA live region to ensure that value changes are announced

## Anatomy

<Anatomy
  role="img"
  aria-label="Color field anatomy diagram: Shows a color field component with labels pointing to its parts, including the input, and label elements." />

A color field consists of an input element and a label. `useColorField` automatically manages
the relationship between the two elements using the `for` attribute on the `<label>` element
and the `aria-labelledby` attribute on the `<input>` element.

`useColorField` returns two sets of props that you should spread onto the appropriate element:

<TypeContext.Provider value={docs.links}>
  <InterfaceType properties={docs.links[docs.exports.useColorField.return.id].properties} />
</TypeContext.Provider>

State is managed by the <TypeLink links={statelyDocs.links} type={statelyDocs.exports.useColorFieldState} />
hook from `@react-stately/color`. The state object should be passed as an option to `useColorField`

If there is no visual label, an `aria-label` or `aria-labelledby` prop must be passed instead
to identify the element to screen readers.

## Example

```tsx example export=true
import {useColorField} from '@react-aria/color';
import {useColorFieldState} from '@react-stately/color';

function ColorField(props) {
  let state = useColorFieldState(props);
  let inputRef = React.useRef(null);
  let {
    labelProps,
    inputProps
  } = useColorField(props, state, inputRef);

  return (
    <div style={{display: 'inline-flex', flexDirection: 'column'}}>
      <label {...labelProps}>{props.label}</label>
      <input {...inputProps} ref={inputRef} />
    </div>
  );
}

<ColorField label="Color" />
```

## Usage

The following examples show how to use the `ColorField` component created in the above example.

### Uncontrolled

By default, `ColorField` is uncontrolled. You can set a default value using the `defaultValue` prop.

```tsx example
<ColorField aria-label="Color" defaultValue="#7f007f" />
```

### Controlled

A `ColorField` can be made controlled. The <TypeLink links={statelyDocs.links} type={statelyDocs.exports.parseColor} />
function is used to parse the initial color from a hex string, stored in state.  The `value` and `onChange` props
are used to update the value in state when the edits the value.

```tsx example
import {parseColor} from '@react-stately/color';

function Example() {
  let [color, setColor] = React.useState(parseColor('#7f007f'));
  return (
    <>
      <ColorField aria-label="Color" value={color} onChange={setColor} />
      <p>Current color value: {color.toString('hex')}</p>
    </>
  );
}
```

### Disabled and read only

A `ColorField` can be disabled using the `isDisabled` prop, and made read only using the `isReadOnly` prop.
The difference is that read only color fields are focusable but disabled color fields are not.

```tsx example
<ColorField aria-label="Color" defaultValue="#7f007f" isDisabled />
<ColorField aria-label="Color" defaultValue="#7f007f" isReadOnly />
```

### HTML forms

ColorField supports the `name` prop for integration with HTML forms. The value will be submitted to the server as a hex color string.

```tsx example
<ColorField label="Color" name="color" />
```

## Internationalization

### RTL

In right-to-left languages, color fields should be mirrored. The label should be right aligned,
along with the text in the input. Ensure that your CSS accounts for this.
